#include "FileHandler.h"
#include "File.h"
//#include "../../commons/fuentes/Path.h"

#include <algorithm>

#ifndef ZERO
	#define ZERO 0
#endif

#ifndef UNO
	#define UNO 1
#endif

#ifndef SIZEOF_ENTRY
	#define SIZEOF_ENTRY 200
#endif

#ifndef ERROR
	#define ERROR -1
#endif

//Path * pathHandler = Path::getInstance();

//---------------------------------------------------------------------------
// IMPLEMENTATION OF CLASS "Handler"
//---------------------------------------------------------------------------

Handler::Handler()
	:handler(ZERO),
	filename(NULL),
	size(ZERO)
{
}

Handler::Handler(const Handler &toCopy)
	:handler(ZERO),
	filename(NULL),
	size(ZERO)
{
	if(filename != NULL)
		delete []filename;
	filename = new char[toCopy.size];
	memcpy(filename, toCopy.filename, toCopy.size);
	size = toCopy.size;
	handler = toCopy.handler;
}

Handler::~Handler()
{
	if(filename != NULL)
		delete []filename;
}

void Handler::set(int id, const char *name, unsigned int s)
{
	size = s;
	handler = id;

	if(name != NULL && s != ZERO)
	{
		if(filename != NULL)
			delete []filename;
		filename = new char[s];
		memcpy(filename, name, s);
	}
}

void Handler::get(int &id, char *name, unsigned int &s)
{
	id = handler;
	if(filename != NULL && name != NULL)
		memcpy(name, filename, size);
	s = size;
}

const Handler &Handler::operator=(const Handler & toAssign)
{
	if(this != &toAssign)
	{
		size = toAssign.size;
		handler = toAssign.handler;

		if(toAssign.filename != NULL && toAssign.size != ZERO)
		{
			if(filename != NULL)
				delete []filename;
			filename = new char[toAssign.size];
			memcpy(filename, toAssign.filename, toAssign.size);
		}
		
	}
	return *this;
}

bool Handler::operator<(const Handler & right)
{
	return (handler < right.handler);
}

bool Handler::operator==(const Handler & right)
{
	return (handler == right.handler);
}

//---------------------------------------------------------------------------
// IMPLEMENTATION OF CLASS "FileHandler"
//---------------------------------------------------------------------------

FileHandler::FileHandler()
	: isModified(false)
{
}

FileHandler::~FileHandler()
{
	handlers.clear();
}

void FileHandler::Create()
{
	// Con el Create ya queda creado el archivo 
	unsigned int count = ZERO;
	//File* file = new File(pathHandler->getPathMetadataOrganization());
	File* file = new File();
	file->open("MetadataOrganization.dat");
	if(file->getSize("MetadataOrganization.dat") == ZERO)
		file->write((char*)&count, sizeof(unsigned int));
	file->close();
	delete file;
}

void FileHandler::Open()
{
	// Levanto todos los handlers de disco
	//File* file = new File(pathHandler->getPathMetadataOrganization());
	File* file = new File();
	unsigned int count;
	int id = UNO;
	char entry[SIZEOF_ENTRY];

	file->open("MetadataOrganization.dat");

	file->read((char*)&count, sizeof(unsigned int));

	for(unsigned int i = ZERO; i < count; i++)
	{
		Handler handler;
		file->read((char*)entry, SIZEOF_ENTRY);
		
		handler.set(id, entry, strlen(entry) + UNO);
		handlers.push_back(handler);
		id++;
	}
	file->close();

	delete file;
}

int FileHandler::Add(const char* filename)
{
	Handler handler;
	handler.set(handlers.size() + UNO, filename, strlen(filename));
	handlers.push_back(handler);
	isModified = true;
	return handlers.size();
}

void FileHandler::Remove(int id)
{
	Handler handler;
	handler.set(id, NULL, ZERO);
	std::vector<Handler>::iterator it = std::find(handlers.begin(), handlers.end(), handler);
	isModified = true;
	handlers.erase(it);
}

int FileHandler::Get(const char* filename)
{
	std::vector<Handler>::iterator it;
	int handler;
	unsigned int size;
	char name[SIZEOF_ENTRY];
	bool find = false;

	for(it = handlers.begin(); it != handlers.end() && !find; it++)
	{
		it->get(handler, name, size);

		if(strncmp(name, filename, size) == ZERO)
			find = true;
	}
	if(find)
		return handler;
	else
		return ERROR;
}

void FileHandler::Get(int id, char* filename)
{
	Handler handler;
	handler.set(id, NULL, ZERO);
	std::vector<Handler>::iterator it = std::find(handlers.begin(), handlers.end(), handler);
	unsigned int size;
	
	if(it != handlers.end())
		it->get(id, filename, size);
}

void FileHandler::Close()
{
	File* file;
	unsigned int count = handlers.size();
	std::vector<Handler>::iterator it;
	int id;
	char endName = '\0';
	char entry[SIZEOF_ENTRY]={0};
	char trash[SIZEOF_ENTRY]={0};
	unsigned int size=0;

	if(isModified)
	{
		//file = new File(pathHandler->getPathMetadataOrganization());
		file = new File();

		file->open("MetadataOrganization.dat");

		file->write((char*)&count, sizeof(unsigned int));
	
		for(it = handlers.begin(); it != handlers.end(); it++)
		{
			it->get(id, entry, size);
			file->write((char*)entry, size);
			file->write((char*)&endName, sizeof(char));
			file->write((char*)trash, SIZEOF_ENTRY - size - sizeof(char));
		}
		file->close();
		delete file;
	}
}

void FileHandler::Destroy()
{
	remove("MetadataOrganization.dat");
}


